Skip to content

【架构优化】合并 prepareWorkbenchContext 中 6 处重复的会话读取为 storedAssistantSession - #776

Open
fx-kurumi wants to merge 3 commits into
Tencent:mainfrom
fx-kurumi:refactor/workbench-stored-session-774
Open

fx-kurumi wants to merge 3 commits into
Tencent:mainfrom
fx-kurumi:refactor/workbench-stored-session-774

Conversation

@fx-kurumi

Copy link
Copy Markdown
Collaborator

Closes #774

改了什么

  • internal/httpapi/assistant_shared.go:新增 (*assistantHandlers).storedAssistantSession(id, userID),空 ID 直接返回未找到,其余统一经 assistantStorageOwner 找到存储槽位后读取,把「共享/项目会话按创建者归属存储」这条规则收在一处。
  • internal/httpapi/assistant_workbench.go:prepareWorkbenchContext 开头读一次会话存入 stored, hasStored,后续「会话属于其他项目」校验、关联需求上下文、讨论分支提示、附件作者回退、子 Agent resume 复用全部复用这份结果;原 6 处重复查询收敛为 1 处。历史附件收集抽成纯函数 historicalAttachmentIDs(session, found, projectID)。workspaceTurnContext 同步改用新 helper。
  • 新增 internal/httpapi/assistant_workbench_session_test.go。

为什么

同一次请求里把同一个会话从库里读 5–6 次,每处再各自判空,读起来像 6 件不同的事;归属规则散落各调用点,容易漏改。

怎么验证

  • gofmt -l internal/httpapi/ 无输出;go vet ./internal/httpapi/ 通过。
  • go test ./internal/httpapi/ -count=1 全部通过,包含新增用例:空 ID / 未知 ID 返回未找到、其他用户读不到私有会话、历史附件只继承同项目非共享会话。
  • 行为不变:错误文案、判断顺序、附件覆盖规则与共享会话不继承附件的语义均原样保留。

🤖 Generated with Claude Code

…Tencent#774)

按存储归属读取当前会话的写法在 assistant_workbench.go 里重复了 6 次,
新增 (*assistantHandlers).storedAssistantSession 收拢这条归属规则,
prepareWorkbenchContext 开头只读一次并复用结果;历史附件收集抽成
historicalAttachmentIDs 纯函数。错误文案、判断顺序与附件覆盖语义不变。

Co-Authored-By: Claude Code <noreply@anthropic.com>
@fx-kurumi

Copy link
Copy Markdown
Collaborator Author

全量 go test ./internal/httpapi/ -count=1 结果:仅 2 个用例失败,均为本容器没有 Chromium 导致(与本次改动无关):

  • TestMainBotBrowserStartsAndDrivesRunBrowser:Agent 浏览器启动失败:当前运行环境不支持,或 Chromium 不可用
  • TestBrowserStreamPushesFramesAndRunsCommands:同一原因

其余全部通过,包括新增的 TestStoredAssistantSessionReadsCallerSlotAndTreatsEmptyIDAsMissing、TestHistoricalAttachmentIDsKeepsOnlyThisProjectsUnownedAttachments,以及所有 Workbench 用例。gofmt -l internal/httpapi/ 无输出,go vet ./internal/httpapi/ 通过。

… issue checks

Co-Authored-By: Claude Code <noreply@anthropic.com>
@fx-kurumi

Copy link
Copy Markdown
Collaborator Author

补测试(自动检查,head 63bb1a5 → d4b9428)

补了什么:新增 internal/httpapi/assistant_workbench_stored_session_guard_test.go(只加测试文件,没改实现):

  • TestPrepareWorkbenchContextRefusesConversationOfAnotherProject:存在 workbench 项目的会话拿到 other 项目里续聊要返回「会话属于其他项目」;同项目续聊、未保存过的新会话 ID 不受影响。
  • TestPrepareWorkbenchContextValidatesAndInjectsStoredSessionIssue:会话绑定的主需求要注入「当前会话关联的主需求」上下文;需求移到别的项目后,下一轮要返回「需求不存在或不属于当前项目」。

为什么:这次把 6 处会话读取合并成一次 storedAssistantSession,我对改动点做了 9 个变异,原有测试漏了 2 个:

变异 原测试 补测后
去掉 hasStored && stored.ProjectID != req.ProjectID 跨项目拦截 漏 发现
跳过 stored.IssueID 的校验与注入 漏 发现
storedAssistantSession 不按存储 owner 读 / workspaceTurnContext 不按 owner 读 / 共享会话继承附件 / 历史附件丢弃 / 附件 owner 不取历史作者 / 跳过分支会话提示 / 不复用角色 Agent 发现 发现

本地验证(Go 1.26.11):gofmt -l internal/httpapi 无输出;go vet ./internal/httpapi/ 通过;go test ./internal/httpapi/ -count=1 -skip Browser → ok agentflow/internal/httpapi 152.408s。不加 -skip 时只有 TestMainBotBrowserStartsAndDrivesRunBrowser、TestBrowserStreamPushesFramesAndRunsCommands 失败,原 head 上同样失败,是本地没有可用 Chromium,与本 PR 无关。

@fx-kurumi fx-kurumi left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review head d4b9428:结论通过(等同 Approve;作者和评审账号相同,所以用 Comment)

等价性核对

  • internal/httpapi/assistant_shared.go:29-34 的 storedAssistantSession 遇到 id == "" 直接返回未找到。repo 层的 AssistantSession(internal/repo/assistant.go:29-33)本来就对空 ID 和纯空白 ID 返回 false,所以原来没加保护的读取(历史附件、workspaceTurnContext)行为不变。
  • assistant_workbench.go:204-208:跨项目校验和 historicalAttachmentIDs 的先后顺序、报错文案都没变,!Shared && ProjectID == req.ProjectID 过滤也保留了。
  • 原来分 6 次读会话,现在只读一次快照(:215、:226、:326、:357、workspaceTurnContext)。核对过:几次读取之间没有任何代码写会话,stored 也没被修改(被修改的只有 req.Messages)。唯一的差别是函数执行过程中不会再读到其他请求的并发写入,几处读到的数据反而更一致。

评论核对:作者补的 guard 测试覆盖了原来漏掉的 2 个变异(跨项目拒绝、已存需求的检查与注入),测试有效。没有其他 review 意见。

本地验证(Go 1.26.11):gofmt 和 vet 通过;-run 'StoredAssistantSession|HistoricalAttachment|PrepareWorkbenchContext|Workbench|WorkspaceTurn' 通过。全包只有 2 个 Chromium 用例失败,main 上同样失败。和 main 无冲突,CI 16/16 通过。不涉及界面。

… and attachment authors in workbench context

Co-Authored-By: Claude Code <noreply@anthropic.com>
@fx-kurumi

Copy link
Copy Markdown
Collaborator Author

补测试(自动巡检,head 63bb1a5 → 77d9593)

为什么补:对 prepareWorkbenchContext / storedAssistantSession 做 19 种变异,PR 自带测试只发现 12 种(合并成组、在完整包上复跑确认不是过滤问题)。漏的:

  • 去掉「会话属于其他项目」的检查(复用别的项目里已存档的会话);
  • 去掉存档会话关联主需求那段上下文;
  • 跳过 validateSessionIssue 的报错;
  • 去掉讨论分支提示,或反过来只要有存档会话就加分支提示;
  • 附件归属人总是取调用者或总是取 stored.UserID,而不按消息作者。

补了什么:新增 internal/httpapi/assistant_workbench_session_guard_test.go

  • TestWorkbenchContextRejectsStoredConversationOfAnotherProject:peer 存在自己名下、owner 存在自己名下的 workbench 会话,从 another 或空项目复用都必须报「会话属于其他项目」,在自己项目里要成功;未存档的新会话可在允许的项目里开始。
  • TestWorkbenchContextCarriesStoredIssueAndBranchNotes:owner 通过存储归属人读到 peer 的会话,带上主需求标题与讨论分支提示;普通会话与未存档会话不出现这两段;关联需求已迁到别的项目时必须报「需求不存在或不属于当前项目」。
  • TestWorkbenchContextResolvesEarlierAttachmentsToTheirAuthor:会话存在 owner 名下但第 0 条消息由 peer 发出、附件在 peer 目录,owner 与 peer 两种调用方下 attachmentOwners 都要按消息作者对应到各自用户,两个附件 ID 都在。

19 种变异剩 1 个等价变异(去掉空 id 判断,repo.AssistantSession 自己就返回 false)。

本地验证:gofmt -l 无输出;go vet ./internal/httpapi/ 通过;go test ./internal/httpapi/ -run 'Workbench|PrepareWorkbenchContext' 通过(含 d4b9428 的同主题测试,两文件无符号冲突);撤掉本次测试、换回合并基点代码后新测试同样通过,说明重构未改变行为。整包只有两个已知的本地浏览器测试失败。只新增测试文件。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

【架构优化】合并 prepareWorkbenchContext 中 6 处重复的会话读取为 storedAssistantSession

1 participant